package tr.com.netgis.web;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.MarshalDate;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.PropertyInfo;

import tr.com.netgis.pojo.NGLocation;
import tr.com.netgis.pojo.NameValues;
import tr.com.netgis.util.Constants;
import tr.com.netgis.util.Status;
import tr.com.netgis.util.Utility;

/**
 * 
 * @author NetGis
 * 
 */
public class SetLocationRequest implements KvmSerializable {

	private NGLocation location;
	private String serverUrl;
	
	@Deprecated
	private String grName;
	

	private String deviceCode;
	private double lastLocationX;
	private double lastLocationY;
	private Status status;
	private Date tarihSaat;
	private String speed;
	private Collection<NameValues> nameValues;

	private RequestHandler handler;
	
	public RequestHandler getHandler() {
		return handler;
	}

	public void setHandler(RequestHandler handler) {
		this.handler = handler;
	}

	public static int getpDeviceCode() {
		return P_DEVICE_CODE;
	}

	public double getLastLocationX() {
		return lastLocationX;
	}

	public void setLastLocationX(double lastLocationX) {
		this.lastLocationX = lastLocationX;
	}

	public double getLastLocationY() {
		return lastLocationY;
	}

	public void setLastLocationY(double lastLocationY) {
		this.lastLocationY = lastLocationY;
	}

	public Date getTarihSaat() {
		return tarihSaat;
	}

	public void setTarihSaat(Date tarihSaat) {
		this.tarihSaat = tarihSaat;
	}

	public Collection<NameValues> getNameValues() {
		return nameValues;
	}

	public void setNameValues(Collection<NameValues> nameValues) {
		this.nameValues = nameValues;
	}

	public String getServerUrl() {
		return serverUrl;
	}

	public void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	@Deprecated
	public String getGrName() {
		return grName;
	}

	@Deprecated
	public void setGrName(String grName) {
		this.grName = grName;
	}

	/**
	 * In order to add to url for test<br>
	 * No effect
	 */
	@Deprecated
	private String sessionId;
	
	/**
	 * Session id is not used<br>
	 * This property has no effect
	 * @param sessionId
	 */
	@Deprecated	
	public String getSessionId() {
		return sessionId;
	}

	/**
	 * Session id is not used<br>
	 * This property has no effect
	 * @param sessionId
	 */
	@Deprecated
	public void setSessionId(String sessionId) {
		this.sessionId = sessionId;
	}

	public SetLocationRequest(NGLocation location) {
		this();
		init(location);
	}

	private void init(NGLocation location) {
		this.deviceCode = Utility.getDeviceId();
		if (location != null) {
			this.location = location;
			this.status = location.getStatus();
			this.lastLocationX = location.getLat();
			this.lastLocationY = location.getLon();
			this.speed = Float.toString(location.getSpeed());
			this.tarihSaat = new Date(location.getTarihSaat());			
		}
	}
	
	public SetLocationRequest() {
		super();
		this.handler = new RequestHandler();
		this.status = Status.UYGULAMA_ACILDI;
		this.grName = "YAZILIM";
		init(null);
	}

	public NGLocation getLocation() {
		return location;
	}

	/**
	 * Sets this objects related properties.
	 * @param location
	 */
	public void setLocation(NGLocation location) {
		this.location = location;
		init(location);
	}

	/**
	 * Cihazın device id'si olmalı
	 * @return
	 */
	public String getDeviceCode() {
		return deviceCode;
	}

	public void setDeviceCode(String deviceCode) {
		this.deviceCode = deviceCode;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public String getSpeed() {
		return speed;
	}

	public void setSpeed(String speed) {
		this.speed = speed;
	}
	
	public static final int P_DEVICE_CODE = 0;
	public static final int P_LAT = 1;
	public static final int P_LON = 2;
	public static final int P_TARIH_SAAT = 3;
	public static final int P_SPEED = 4;
	public static final int P_STATUS = 5;
	public static final int P_NAMEVALUES = 6;
	
	
	@Override
	public Object getProperty(int index) {
		switch (index) {
        case P_DEVICE_CODE:
            return this.getDeviceCode();  
        case P_LAT:
            return this.getLastLocationX();        
        case P_LON:
            return this.getLastLocationY();
        case P_TARIH_SAAT: 
            return this.getTarihSaat();
        case P_SPEED:
            return this.getSpeed();
        case P_STATUS:
            return this.getStatus().getCode();
        case P_NAMEVALUES:
            return this.getNameValues();
        default:
            return null;
        }
	}


	@Override
	public int getPropertyCount() {
		return 7;
	}


	public PropertyInfo getPropertyInfo(int index) {
		PropertyInfo info = new PropertyInfo();
		getPropertyInfo(index, null, info);
		return info;
	}

	@Override
	public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
		 switch (index)
	        {
	        case P_DEVICE_CODE:
	            info.type = PropertyInfo.STRING_CLASS;
	            info.name = Constants.P_NAME_DEVICECODE;  
	            info.setValue(this.getDeviceCode());
	            break;
	        case P_LAT:
	            info.type = MarshalFloat.class;
	            info.name = Constants.P_NAME_LAT;
	            info.setValue(this.getLastLocationX());
	            break;         
	        case P_LON:
	            info.type = MarshalFloat.class;
	            info.name = Constants.P_NAME_LON;
	            info.setValue(this.getLastLocationY());
	            break;
	        case P_TARIH_SAAT:
	            info.type = MarshalDate.DATE_CLASS;
	            info.name = Constants.P_NAME_TARIH_SAAT;
	            info.setValue(this.getTarihSaat());
	            break;
	        case P_SPEED:
	            info.type = PropertyInfo.STRING_CLASS;
	            info.name = Constants.P_NAME_SPEED;
	            info.setValue(this.getSpeed());
	            break;
	        case P_STATUS:
	            info.type = PropertyInfo.INTEGER_CLASS;
	            info.name = Constants.P_NAME_STATUS;
	            info.setValue(this.getStatus().getCode());
	            break;
	        case P_NAMEVALUES:
	            info.type = PropertyInfo.TRANSIENT;
	            info.name = "nameValues";
	            //TODO
	            break;           
	        default:
	            break;
	        }				
	}


	@Override
	public void setProperty(int index, Object value) {
		switch (index) {
        case P_DEVICE_CODE:
        	deviceCode = value.toString(); 
            break;
        case P_LAT:
        	lastLocationX = (Double)value;
            break;         
        case P_LON:
        	lastLocationY = (Double)value;
            break;
        case P_TARIH_SAAT:
        	tarihSaat = new Date((Long)value);
            break;
        case P_SPEED:
        	speed = value.toString(); 
            break;
        case P_STATUS:
        	status = Status.valueOf(value.toString());
            break;
        case P_NAMEVALUES:
        	nameValues = new ArrayList<NameValues>();
        	//TODO
            break;
        default:
            break;
        }		
	}
	
	public String toString(){
		SimpleDateFormat sdf = Utility.createSimpleDateFormat();
		return MessageFormat.format("" +
			"Cihaz Kodu: {5}\n" +
			"Konum Tarihi:{0}\n" +
			"Lat: {1}\n" +
			"Lon: {2}\n" +
			"Hız: {3}\n" +
			"Durum: {4}\n", 
			sdf.format(this.getTarihSaat()),
			Double.toString(this.getLastLocationX()),
			Double.toString(this.getLastLocationY()),
			this.getSpeed(),
			this.getStatus(),
			this.getDeviceCode()
		);	
	}
	
}
